#pragma once


#include <cstdint>
#include <cstdlib>

#include "oled_include_config.hpp"


namespace oled_basic {

    /**
     * @brief 定义OLED 屏幕的硬件属性
     *
     */
    struct OledProperty {
        // 初始化指令放在数组里逐个发送，似乎大部分屏幕的初始化过程都只要持续发送指令就好了
        // 如果初始化过程有什么额外操作，可以在指令序列里插入特殊标志，然后用对应的backend 解析
        // 用函数指针调用初始化函数不太方便，需要给初始化函数传递很多参数
        const uint8_t *init_sequence;

        PixelIndexType column_count;  // 列数，12864 代表128 列
        PixelIndexType page_count;    // 页数 12864 代表8 页

        uint8_t init_sequence_length;

        uint8_t grayscale_bit;  // 灰阶bit 数，单色屏值为1，四灰阶屏值为2

        // uint_fast8_t grayscale_filling_strategy;

        // uint8_t address;       // I2C 地址，SPI 屏用不着
    };


    /**
     * @brief 发送模式
     *
     */
    enum class txmode : uint_fast8_t {
        cmd,   // 发送指令
        data,  // 发送数据
    };


#ifdef __cpp_concepts

    /**
     * @brief 可以给应用层使用的Backend 对象应该满足的duck-typing 接口
     *
     * @tparam T
     */
    template <typename T>
    concept BackendFeatureSet = requires(T *t) {
        t->begin_tx();
        t->write(static_cast<uint8_t>(0));
        t->write(static_cast<uint8_t *>(nullptr), 0);
        t->end();

        t->set_cursor(0, 0);
    };

#endif


    // class IOledWriter {
    //    public:
    //     virtual void begin_tx(txmode m = txmode::data) = 0;

    //     virtual void write(uint_fast8_t d, txmode m) = 0;

    //     virtual void write(uint8_t *data, size_t len, txmode m) = 0;

    //     virtual int_fast8_t end() = 0;

    //     virtual void set_cursor(uint_fast8_t column, uint_fast8_t page) = 0;
    // };
}  // namespace oled_basic